/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package tuneControllers;

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
import com.mpatric.mp3agic.ID3v1;
import com.mpatric.mp3agic.ID3v2;
import com.mpatric.mp3agic.InvalidDataException;
import com.mpatric.mp3agic.Mp3File;
import com.mpatric.mp3agic.UnsupportedTagException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableModel;
import javazoom.jl.player.Player;
import tuneModels.Database;
import tuneModels.MusicControls;
import tuneModels.Song;
import tuneModels.VolumeControl;
import tuneViews.Mini;
import tuneViews.PlayerApp;
import tuneViews.Volume;


/**
 *
 * @author Israel Agyeman-Premp
 */
public class MiniController {

    Database db;
    Mini p;
    ActionListener actionListener;
    MouseListener mouseListener;
    FileInputStream FIS;
    BufferedInputStream BIS;
    Player player;
    PlayerController aPlayer;
    MusicControls music;
    VolumeControl volume;
    VolumeController vc;
    Volume v = null;
    DefaultTableModel trackTable;
    KeyAdapter keyAdapter;
    KeyListener keyListener;
    String filePath;
    String nowPlaying;
//    MainClass mainClass;

    /**
     * A set of Triggers to know if A function has been Executed
     */
    boolean stopped = true;
    boolean playing = true;
    boolean paused = true;

    /**
     * A method that takes a database and a player class to initialise
     *
     * @param db
     * @param p
     * @param mc
     * @param volume
     * @param aPlayer
     */
    public MiniController(Database db, Mini p, MusicControls mc, VolumeControl volume, PlayerController aPlayer) {
        this.db = db;
        this.p = p;
        this.music = mc;
        this.volume = volume;
        this.aPlayer = aPlayer;
        p.setVisible(true);
        db.initComponents();

    }

    /**
     * A method that controls each element and component of the music player
     * main view has events to play, stop and pause the music player however
     * mouseMotion events and a Volume Controller is called in this class
     */
    public void control() {
        p.displayTrack().setText(aPlayer.getNowPlaying());

        /**
         * The mouse listener takes care of most of the UI elements since they
         * are composed of JLabels
         */
        mouseListener = new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
                if (e.getSource() == p.quickOpen()) {
                    try {
                        openTrack();
                    } catch (IOException ex) {
                        Logger.getLogger(PlayerController.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (UnsupportedTagException ex) {
                        Logger.getLogger(PlayerController.class.getName()).log(Level.SEVERE, null, ex);
                    } catch (InvalidDataException ex) {
                        Logger.getLogger(PlayerController.class.getName()).log(Level.SEVERE, null, ex);
                    }
                } else if (e.getSource() == p.stopBtn()) {
                    if (!stopped) {
                        music.Stop();
                        stopPressed();
                        playing = false;
                        stopped = true;
                        paused = false;
                    } else {
                        System.out.println("Stopped");
                    }
                } else if (e.getSource() == p.playBtn()) {
                    if (!playing) {
                        music.Resume();
                        playPressed();
                        playing = true;
                        stopped = false;
                        paused = false;
                    } else {
                        System.out.println("Already playing");
                    }
                } else if (e.getSource() == p.pauseBtn()) {
                    if (!paused) {
                        music.Pause();
                        pausePressed();
                        playing = false;
                        stopped = false;
                        paused = true;
                    } else {
                        System.out.println("Already paused");
                    }
                } else if (e.getSource() == p.powerBtn()) {
                    if(e.getClickCount()==1){
                        powerOff();
                    }
                    
                } else if (e.getSource() == p.volume()) {
                    if (v == null) {
                        v = new Volume();
                    }
                    vc = new VolumeController(volume, v);
                    vc.control();
                } else if (e.getSource() == p.youTube()) {
                    try {
                        //Set your page url in this string. For eg, I m using URL for Google Search engine
                        String url = "http://www.youtube.com/results?search_query=Ashesi+University";
                        java.awt.Desktop.getDesktop().browse(java.net.URI.create(url));
                    } catch (java.io.IOException ex) {
                        System.out.println(ex.getMessage());
                    }
                }
            }

            @Override
            public void mouseReleased(MouseEvent e) {

            }

            /**
             * Other Abstract methods that need to be implemented
             */
            /*
             * This portion takes care of things that happen when a button is pressed
             */
            @Override
            public void mousePressed(MouseEvent e) {
            }

            @Override
            public void mouseEntered(MouseEvent e) {
            }

            @Override
            public void mouseExited(MouseEvent e) {
            }

        };

        /**
         * The action listener takes care of elements in the JMenu bar
         */
        actionListener = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {

            }
        };

        /* Mouse Events for the JLabel Actions */
        /**
         * This part of the code adds mouse listeners and action listeners to
         * the components
         */
        p.volume().addMouseListener(mouseListener);
        p.displayTrack().addMouseListener(mouseListener);
        p.stopBtn().addMouseListener(mouseListener);
        p.playBtn().addMouseListener(mouseListener);
        p.pauseBtn().addMouseListener(mouseListener);
        p.powerBtn().addMouseListener(mouseListener);
        p.quickOpen().addMouseListener(mouseListener);
        p.youTube().addMouseListener(mouseListener);

    }

    /**
     * Animates the stop button when it is pressed this is mainly done by
     * changing images when they are pressed
     */
    public void stopPressed() {
        p.playBtn().setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/play-04.png")));
        p.pauseBtn().setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/pause-04.png")));
        p.stopBtn().setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/stop-04.png")));

    }

    /**
     * Animates the play button when it is pressed
     */
    public void playPressed() {
        p.playBtn().setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/play-04.png")));
        p.pauseBtn().setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/pause-04.png")));
        p.stopBtn().setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/stop-04.png")));

    }

    /**
     * Animates the paused button when it is pressed
     */
    public void pausePressed() {
        p.playBtn().setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/play-04.png")));
        p.pauseBtn().setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/pause-04.png")));
        p.stopBtn().setIcon(new javax.swing.ImageIcon(getClass().getResource("/icons/stop-04.png")));

    }

    /**
     * This method causes the player to close
     * @return 
     */
    public void powerOff() {
        int ans = JOptionPane.showConfirmDialog(p, "Are You Sure You Want to QUIT?");
        if (ans == 0) {
            p.dispose();
        }
        aPlayer.getPlayer().setVisible(true);
    }

    /**
     * Allows the user to open a song file and automatically plays the song once
     * it is opened.
     *
     * JFile chooser methods makes it open your music directory by default
     *
     * @throws IOException
     * @throws UnsupportedTagException
     * @throws InvalidDataException
     */
    public void openTrack() throws IOException, UnsupportedTagException, InvalidDataException {
        FileNameExtensionFilter filter = new FileNameExtensionFilter("MP3 Files", "mp3", "mp4");
        File workingDirectory = new File(System.getProperty("user.home"));

        JFileChooser choose = new JFileChooser(workingDirectory + "\\Music");
        choose.addChoosableFileFilter(filter);
        int returnVal = choose.showOpenDialog(null);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            music.Stop();
            File myFile = choose.getSelectedFile();
            filePath = (String) myFile.toString();
            nowPlaying = choose.getSelectedFile().getName();
            p.displayTrack().setText(nowPlaying);
            music.Play(filePath);
            playPressed();
            playing = true;
            stopped = false;
            paused = false;
            int songId;
            songId = db.addSong(getSongDetails(filePath));
            if (songId == 0) {
                JOptionPane.showMessageDialog(p, "ID tag value on this song is not valid ", "Failed to Add", 2);
            }
        }

    }

   

    /**
     * A method that gets the details of a song handles situations where ID3
     * values cannot be retrieved
     *
     * @param fileName
     * @return song
     * @throws java.io.IOException
     * @throws com.mpatric.mp3agic.UnsupportedTagException
     * @throws com.mpatric.mp3agic.InvalidDataException
     */
    public Song getSongDetails(String fileName) throws IOException, UnsupportedTagException, InvalidDataException {
        Song newSong = null;
        Mp3File mp3file = new Mp3File(fileName);
        System.out.println("Length of this mp3 is: " + mp3file.getLengthInSeconds() + " seconds");
        System.out.println("Bitrate: " + mp3file.getLengthInSeconds() + " kbps " + (mp3file.isVbr() ? "(VBR)" : "(CBR)"));
        System.out.println("Sample rate: " + mp3file.getSampleRate() + " Hz");
        System.out.println("Has ID3v1 tag?: " + (mp3file.hasId3v1Tag() ? "YES" : "NO"));
        System.out.println("Has ID3v2 tag?: " + (mp3file.hasId3v2Tag() ? "YES" : "NO"));
        System.out.println("Has custom tag?: " + (mp3file.hasCustomTag() ? "YES" : "NO"));
        if (mp3file.hasId3v1Tag()) {

            ID3v1 id3v1Tag = mp3file.getId3v1Tag();
            System.out.println("Track: " + id3v1Tag.getTrack());
            String title = id3v1Tag.getTitle();
            String artist = id3v1Tag.getArtist();
            String time = mp3file.getLengthInSeconds() + "";
            String album = id3v1Tag.getAlbum();
            String path = fileName;
            System.out.println("Album: " + id3v1Tag.getAlbum());
            System.out.println("Year: " + id3v1Tag.getYear());
            System.out.println("Genre: " + id3v1Tag.getGenre() + " (" + id3v1Tag.getGenreDescription() + ")");
            System.out.println("Comment: " + id3v1Tag.getComment());
            Song addedSong = new Song(title, artist, time, album, path);
            newSong = addedSong;
        } else if (mp3file.hasId3v2Tag()) {
            ID3v2 id3v2Tag = mp3file.getId3v2Tag();
            System.out.println("Track: " + id3v2Tag.getTrack());
            String title = id3v2Tag.getTitle();
            String artist = id3v2Tag.getArtist();
            String time = mp3file.getLengthInSeconds() + "";
            String album = id3v2Tag.getAlbum();
            String path = filePath;
            System.out.println("Album: " + id3v2Tag.getAlbum());
            System.out.println("Year: " + id3v2Tag.getYear());
            System.out.println("Genre: " + id3v2Tag.getGenre() + " (" + id3v2Tag.getGenreDescription() + ")");
            System.out.println("Comment: " + id3v2Tag.getComment());
            Song addedSong = new Song(title, artist, time, album, path);
            newSong = addedSong;
        } else if (mp3file.hasCustomTag()) {
            ID3v1 id3v1Tag = mp3file.getId3v1Tag();
            System.out.println("Track: " + id3v1Tag.getTrack());
            String title = id3v1Tag.getTitle();
            String artist = id3v1Tag.getArtist();
            String time = mp3file.getLengthInSeconds() + "";
            String album = id3v1Tag.getAlbum();
            String path = filePath;
            System.out.println("Album: " + id3v1Tag.getAlbum());
            System.out.println("Year: " + id3v1Tag.getYear());
            System.out.println("Genre: " + id3v1Tag.getGenre() + " (" + id3v1Tag.getGenreDescription() + ")");
            System.out.println("Comment: " + id3v1Tag.getComment());
            Song addedSong = new Song(title, artist, time, album, path);
            newSong = addedSong;
        }

        return newSong;
    }
    
    

}
